<?php

  require_once "JooS/Server/Stream/Interface.php";


  abstract class JooS_Server_Stream_Abstract implements JooS_Server_Stream_Interface {
    protected $_streamCreated = null;

    protected $_streamPosition = null;
    
    protected $_streamContent = null;

    abstract protected function stream_get_content($path);

    public function __construct() {
      $this->_streamCreated = time();
      $this->_streamContent = "";
    }

    protected static function _stream_register($protocol, $className) {
      if (!in_array($protocol, stream_get_wrappers()))
        stream_wrapper_register($protocol, $className);
    }

    public function stream_open($path, $mode, $options, &$opened_path) {
      $this->_streamContent = $this->stream_get_content($path);
      $this->_streamPosition = 0;
        
      return true;
    }
    
    public function stream_read($count) {
      $ret = substr($this->_streamContent, $this->_streamPosition, $count);
      $this->_streamPosition += strlen($ret);
      return $ret;
    }
    
    public function stream_tell() {
      return $this->_streamPosition;
    }

    public function stream_eof() {
      return $this->_streamPosition >= strlen($this->_streamContent);
    }

    public function stream_stat() {
      return array(
        "size" => strlen($this->_streamContent), 
        "atime" => $this->_streamCreated, 
        "mtime" => $this->_streamCreated, 
        "ctime" => $this->_streamCreated, 
      );
    }

    public function url_stat($path, $flags) {
      return $this->stream_stat();
    }

    public function stream_seek($offset, $whence) {
      switch ($whence) {
        case SEEK_SET:
          if ($offset < strlen($this->_streamContent) && $offset >= 0) {
            $this->_streamPosition = $offset;
            return true;
          }
          else {
            return false;
          }
          break;
        case SEEK_CUR:
          if ($offset >= 0) {
            $this->_streamPosition += $offset;
            return true;
          }
          else {
            return false;
          }
          break;
        case SEEK_END:
          if (strlen($this->_streamContent) + $offset >= 0) {
            $this->_streamPosition = strlen($this->_streamContent) + $offset;
            return true;
          }
          else {
            return false;
          }
          break;
        default:
          return false;
      }
    }
  }

?>